package com.woniuxy.classdeans.sender;

import com.woniuxy.commons.entity.wyh.DivideClasses;
import com.woniuxy.commons.enums.MessageTypeEnum;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.UUID;

/**
 * @Author weizihan
 * @Date 2020/7/20 2020/7/20
 * @Description 分班消息发送
 * @Since version-1.0
 */
@Component
public class GradeSender implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback{
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    public static final String DIVIDE = null;
    
    public void send(DivideClasses divideClasses){
        System.out.println("发送通知分班"+new Date());
        //指定一个消息id
        CorrelationData correlationData = new CorrelationData();
        String rid = UUID.randomUUID().toString();  //随机生成id
        correlationData.setId(rid);
        //将消息缓存在redis中
        redisTemplate.opsForValue().set(rid,divideClasses);
        redisTemplate.opsForValue().set(MessageTypeEnum.DIVIDE.getName(),divideClasses);
        rabbitTemplate.convertAndSend("dDirectExchange","stClass",divideClasses,correlationData);
    }

    //无论交换机是否接受到消息，都会自动调用此方法，如果消息无法返回，就会返回消息的id--回调函数
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        //设置重新发送的次数
        int sum = 0;
           if (!b){
               //获取在redis中存储的消息
               DivideClasses divideClasses = (DivideClasses)redisTemplate.opsForValue().get(correlationData.getId());
                if (sum <= 3){
                    redisTemplate.delete(correlationData.getId());
                    redisTemplate.opsForValue().set(correlationData.getId(),divideClasses);
                    //重新发送
                    send(divideClasses);
               }
           }
        System.out.println("发送失败");
    }

    //消息无法到达指定的消息队列时，调用该方法
    @Override
    public void returnedMessage(Message message, int i, String s, String s1, String s2) {
        System.out.println("消息未到达消息队列：1.消息队列不存在，2.消息队列和交换机未绑定，3.路由出错");
        System.out.println("错误代码："+i);
        System.out.println("原因："+s);
    }

    //手动设置消息确认

    //设置启动回调函数
    @PostConstruct //对象创建或注入完毕自动调用该方法
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }
}
